package com.AFH.test;

import java.util.ArrayList;
import java.util.HashMap;

//import android.R.integer;

import android.graphics.*;
import android.media.AudioManager;
import android.media.SoundPool;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends SurfaceView implements SurfaceHolder.Callback {

	ViewSwitcher vs;
	// Arrays & Data
	Tower[][] Tower;
	Monster[] monsters;
	int BuildSelect = -1;
	int selectedRect;
	int selectedRow;
	int selectedCol;

	// sound

	HashMap<Integer, Integer> GameSoundMap;
	// Threads

	int monsterNumber;
	// Random rnd=new Random();

	// Threads
	StartQueueThread sqt;
	GameThread gt;
	AttackSoundThread ast_nature;
	AttackSoundThread ast_fire;
	AttackSoundThread ast_thunder;
	AttackSoundThread ast_monsterwhitelack;
	AttackSoundThread ast_monsterwhite;
	AttackSoundThread ast_monsterboss;
	AttackSoundThread ast_boom;
	AttackSoundThread gameover_mic;
	boolean paused = false;
	boolean onbackevent = false;
	Thread surpriseThread;
	// Draw
	// Bitmap memBm;
	// Canvas canvas;
	// Rect
	ArrayList<Rect> tempRect = new ArrayList<Rect>();
	Rect temp;
	Rect DrawTower;

	// Touch
	boolean isConfirmed = false;
	int touchx;
	int touchy;
	int touchRecord = 0;
	int selected_TowerNo = 0;
	// Test Data
	Tower testOT;
	int score = 1024;
	// int money = 100;
	int bombnum = 0;
	// Surprise
	Surprise surprise;
	int surpriseRandom = -1;
	boolean surpriseCatched = false;
	boolean surpriseOccured = false;
	// String surprise = null;
	Rect surpriseRect = null;

	// Animation
	int status = 0;
	int bgx = 800;
	int bgy = 480;
	// Bomb
	Bomb bomb = null;
	// Stages
	Text text = null;
	int currentstage = 0;
	SoundPool GameMicPool;

	public GameView(ViewSwitcher vs) {
		super(vs);
		this.vs = vs;
		getHolder().addCallback(this);
		gt = new GameThread(this, getHolder());
		ast_fire = new AttackSoundThread(this);
		ast_nature = new AttackSoundThread(this);
		ast_thunder = new AttackSoundThread(this);
		ast_monsterwhitelack = new AttackSoundThread(this);
		ast_monsterwhite = new AttackSoundThread(this);
		ast_monsterboss = new AttackSoundThread(this);
		gameover_mic = new AttackSoundThread(this);
		ast_boom = new AttackSoundThread(this);
		tempRect = GameData.creatArrayRect();
		// memBm = Bitmap.createBitmap(800, 480, Bitmap.Config.RGB_565);
		// canvas = new Canvas(memBm);
		initStageData();
		initGameSound(this);

	}

	public void initStageData() {
		Tower = new Tower[GameData.MapRows][GameData.MapCols];
		nextWave(currentstage);
		Paint tmppaint = new Paint();
		tmppaint.setColor(Color.RED);
		tmppaint.setTextSize(100f);
		text = new Text("Stage " + (currentstage + 1), 200f, 200f, tmppaint);
		text.start();

		/*
		 * sqt = new StartQueueThread(); switch (currentstage) { case 1: //
		 * spriteMonsters = new //
		 * Sprite[GameData.WaveNum_S1][GameData.MonstersEachWave_S1]; //
		 * Initialize surprise Rect
		 * 
		 * spriteMonsters = new
		 * Monster[GameData.WaveNum_S1][GameData.MonstersEachWave_S1];
		 * currentWaveNum = GameData.WaveNum_S1; currentMonstersEachWave =
		 * GameData.MonstersEachWave_S1; for (int wave = 0; wave <
		 * GameData.MonsterTable_S1.length; wave++) { for (int i = 0; i <
		 * GameData.MonstersEachWave_S1; i++) { spriteMonsters[wave][i] = new
		 * Monster(800, GameData.MonsterTable_S1[wave][1][i]);
		 * spriteMonsters[wave][i].setCurrentSegment(0);
		 * spriteMonsters[wave][i].makeAnimation(GameData.monsterA);
		 * sqt.addSprite(GameData.MonsterTable_S1[wave][2][i],
		 * spriteMonsters[wave][i]); } } }
		 */
	}

	public void initGameSound(GameView gv) {
		GameMicPool = new SoundPool(10, AudioManager.STREAM_MUSIC, 100);
		GameSoundMap = new HashMap<Integer, Integer>();

		GameSoundMap.put(4, GameMicPool.load(vs, R.raw.thunder, 1));
		GameSoundMap.put(1, GameMicPool.load(vs, R.raw.fire_atk, 1));
		GameSoundMap.put(3, GameMicPool.load(vs, R.raw.nature_atk, 1));
		GameSoundMap.put(5, GameMicPool.load(vs, R.raw.monstera_atk1, 1));
		GameSoundMap.put(6, GameMicPool.load(vs, R.raw.monstera_atk2, 1));
		GameSoundMap.put(7, GameMicPool.load(vs, R.raw.monstera_atk3, 1));
		GameSoundMap.put(8, GameMicPool.load(vs, R.raw.monsterb_atk1, 1));
		GameSoundMap.put(9, GameMicPool.load(vs, R.raw.monsterb_atk2, 1));
		GameSoundMap.put(10, GameMicPool.load(vs, R.raw.monsterb_atk3, 1));
		GameSoundMap.put(11, GameMicPool.load(vs, R.raw.monsterc_atk1, 1));
		GameSoundMap.put(12, GameMicPool.load(vs, R.raw.monsterc_atk2, 1));
		GameSoundMap.put(13, GameMicPool.load(vs, R.raw.suprise_open, 1));
		GameSoundMap.put(14, GameMicPool.load(vs, R.raw.boom, 1));
		GameSoundMap.put(15, GameMicPool.load(vs, R.raw.gameover, 1));

	}

	public void pause() {
		paused = true;
		sqt.pauseAnimation();
		for (int i = 0; i < monsterNumber; i++) {
			monsters[i].pauseAnimation();
			if (monsters[i].atStarted() && monsters[i].at.started())
				monsters[i].at.pauseAnimation();
		}

		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null) {
					Tower[i][j].pauseAnimation();
					if (Tower[i][j].atStarted() && Tower[i][j].at.started())
						Tower[i][j].at.pauseAnimation();
				}
			}
		}

	}

	public void stop() {
		sqt.stopAnimation();
		for (int i = 0; i < monsterNumber; i++) {
			monsters[i].stopAnimation();

			if (monsters[i].atStarted() && monsters[i].at.started())
				monsters[i].at.stopAttack();
		}

		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null) {
					Tower[i][j].stopAnimation();

					if (Tower[i][j].atStarted() && Tower[i][j].at.started())
						Tower[i][j].at.stopAttack();
				}
			}
		}
		ast_fire.flag = false;
		ast_fire.soundon = false;
		ast_nature.flag = false;
		ast_nature.soundon = false;
		ast_thunder.flag = false;
		ast_thunder.soundon = false;
		ast_monsterwhitelack.flag = false;
		ast_monsterwhitelack.soundon = false;
		ast_monsterwhite.soundon = false;
		ast_monsterboss.flag = false;
		ast_monsterboss.soundon = false;
		GameMicPool.release();
		if (text != null && text.isAlive())
			text.flag = false;
		if (surprise != null)
			surprise.flag = false;
		if (bomb != null && bomb.st.isAlive())
			bomb.stopAnimation();

	}

	public void resume() {
		paused = false;
		sqt.resumeAnimation();
		for (int i = 0; i < monsterNumber; i++) {

			monsters[i].resumeAnimation();
			if (monsters[i].atStarted())
				monsters[i].at.resumeAnimation();
		}

		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null) {
					Tower[i][j].resumeAnimation();
					if (Tower[i][j].atStarted())
						Tower[i][j].at.resumeAnimation();
				}
			}
		}
	}

	public Monster firstMonster(int line) {
		Monster tmpMonster = null;
		float smallest = 800;
		for (int i = 0; i < monsterNumber; i++) {
			if (!monsters[i].isdead()) {
				if (monsters[i].getyPos() == line
						&& monsters[i].getxPos() < smallest) {
					smallest = monsters[i].getxPos();
					tmpMonster = monsters[i];
				}
			}

		}
		return tmpMonster;
	}

	public Monster firstMonsterInRange(Tower tower) {
		Monster tmpMonster = null;
		float smallest = 800;
		for (int i = 0; i < monsterNumber; i++) {
			if (!monsters[i].isdead()) {
				if (monsters[i].getyPos() == tower.getyPos()
						&& monsters[i].getxPos() > tower.getxPos()
						&& monsters[i].getxPos() < smallest
						&& inRange(monsters[i], tower)) {
					smallest = monsters[i].getxPos();
					tmpMonster = monsters[i];
				}
			}
		}

		return tmpMonster;
	}

	public Tower firstTowerInRange(Monster monster) {
		Tower tmpTower = null;
		float smallest = -1;
		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null && !Tower[i][j].isdead()
						&& Tower[i][j].towerstatus == GameData.HAVE_BUILT) {
					if (Tower[i][j].getyPos() == monster.getyPos()
							&& Tower[i][j].getxPos() < monster.getxPos()
							&& Tower[i][j].getxPos() > smallest
							&& inRange(Tower[i][j], monster)) {
						smallest = Tower[i][j].getxPos();
						tmpTower = Tower[i][j];
					}
				}
			}
		}
		return tmpTower;
	}

	public Tower firstTower(int line) {
		Tower tmpTower = null;
		float smallest = 0;
		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null && !Tower[i][j].isdead()
						&& Tower[i][j].towerstatus == GameData.HAVE_BUILT) {
					if (Tower[i][j].getyPos() == line
							&& Tower[i][j].getxPos() > smallest) {
						smallest = Tower[i][j].getxPos();
						tmpTower = Tower[i][j];
					}
				}
			}
		}
		return tmpTower;
	}

	// Judge if monster is in the attack range of the tower.
	public boolean inRange(Monster monster, Tower tower) {
		if (tower.inAttackRange(monster.getxPos() - tower.getxPos()))
			return true;
		else
			return false;
	}

	// Judge if tower is in the attack range of the monster
	public boolean inRange(Tower tower, Monster monster) {
		if (monster.inAttackRange(monster.getxPos() - tower.getxPos()))
			return true;
		else
			return false;
	}

	public void drawTowers(Canvas canvas) {
		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null && Tower[i][j].isdead()) {
					Tower[i][j] = null;
				}
				if (Tower[i][j] != null
						&& Tower[i][j].towerstatus != GameData.NOT_BUILT) {
					if (!Tower[i][j].st.isAlive())
						Tower[i][j].startAnimation();
					Tower[i][j].drawself(canvas);
					// GameData.TowerStatus[i][j]=1;
				}
				// else GameData.TowerStatus[i][j]=0;
			}
		}
	}

	public void drawMonsters(Canvas canvas) {
		for (int i = 0; i < monsterNumber; i++) {
			if (monsters[i].st.isAlive()) {
				monsters[i].drawself(canvas);
			}
		}

	}

	public void drawAttack(Canvas canvas) {
		ast_monsterwhitelack.soundon = false;
		ast_monsterwhite.soundon = false;
		ast_monsterboss.soundon = false;

		for (int i = 0; i < monsterNumber; i++) {
			if (monsters[i].st.isAlive()) {
				Tower fstTower = firstTowerInRange(monsters[i]);
				if (fstTower != null) {
					monsters[i].attack(fstTower, GameData.MONSTERAATTACK);
					if (monsters[i].atStarted() && !paused) {
						monsters[i].at.drawself(canvas);
						if (monsters[i].getAttribute() == GameData.MONSTER_black) {
							int monstersound = GameData.rnd.nextInt(3);
							if (monstersound == 0) {
								ast_monsterwhitelack.MicNO = 5;
								ast_monsterwhitelack.soundon = true;
							}
							if (monstersound == 1) {
								ast_monsterwhitelack.MicNO = 6;
								ast_monsterwhitelack.soundon = true;
							}
							if (monstersound == 2) {
								ast_monsterwhitelack.MicNO = 7;
								ast_monsterwhitelack.soundon = true;
							}
						}
						if (monsters[i].getAttribute() == GameData.MONSTER_white) {
							int monstersound = GameData.rnd.nextInt(3);
							if (monstersound == 0) {
								ast_monsterwhite.MicNO = 8;
								ast_monsterwhite.soundon = true;
							}
							if (monstersound == 1) {
								ast_monsterwhite.MicNO = 9;
								ast_monsterwhite.soundon = true;
							}
							if (monstersound == 2) {
								ast_monsterwhite.MicNO = 10;
								ast_monsterwhite.soundon = true;
							}
						}
						if (monsters[i].getAttribute() == GameData.MONSTER_boss) {
							int monstersound = GameData.rnd.nextInt(2);
							if (monstersound == 0) {
								ast_monsterboss.MicNO = 11;
								ast_monsterboss.soundon = true;
							}
							if (monstersound == 1) {
								ast_monsterboss.MicNO = 12;
								ast_monsterboss.soundon = true;
							}
						}
					} else {
						ast_monsterwhitelack.soundon = false;
						ast_monsterwhite.soundon = false;
						ast_monsterboss.soundon = false;
					}
				}
			}
		}
		ast_thunder.soundon = false;
		ast_fire.soundon = false;
		ast_nature.soundon = false;

		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null
						&& !Tower[i][j].isdead()
						&& Tower[i][j].towerstatus == GameData.HAVE_BUILT) {
					Monster fstMonster = firstMonsterInRange(Tower[i][j]);
					if (fstMonster != null) {

						Tower[i][j].attack(fstMonster, BitmapManager
								.getAttackAni(Tower[i][j].getAttribute()));
						if (Tower[i][j].atStarted() && !paused) {
							Tower[i][j].at.drawself(canvas);
							if (Tower[i][j].getAttribute() == GameData.FIRETOWER) {
								ast_fire.MicNO = GameData.FIRETOWER;
								ast_fire.soundon = true;
							}
							if (Tower[i][j].getAttribute() == GameData.NATURETOWER) {
								ast_nature.MicNO = GameData.NATURETOWER;
								ast_nature.soundon = true;
							}
							if (Tower[i][j].getAttribute() == GameData.THUNDERTOWER) {
								ast_thunder.MicNO = GameData.THUNDERTOWER;
								ast_thunder.soundon = true;
							}

						} else {
							ast_thunder.soundon = false;
							ast_fire.soundon = false;
							ast_nature.soundon = false;
						}

					}

				}

			}
		}

	}

	public boolean lost() {
		for (int i = 0; i < monsterNumber; i++) {
			if (monsters[i].st.isAlive()) {
				if (monsters[i].getxPos() <= 0) {
					GameData.gameProfile.monsterMissed++;
					monsters[i].stopAnimation();
					if (sqt.isAlive())
						sqt.flag = false;
				}
			}
		}

		return GameData.gameProfile.lostGame();
	}

	public void cleanThread(){
		for (int i = 0; i < monsterNumber; i++) {
			if (monsters[i].isdead() && monsters[i].at!=null) {
				monsters[i].at.art.flag=false;
				monsters[i].at.art.spStart=false;
			}
		}
		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null && Tower[i][j].isdead() && Tower[i][j].at!=null) {
					Tower[i][j].at.art.flag=false;
					Tower[i][j].at.art.spStart=false;
				}
			}
		}
	}
	public void drawSurprise(Canvas canvas) {

		if (touchRecord != 1 && !surpriseOccured
				&& GameData.rnd.nextInt(1000) > 990) {
			surpriseOccured = true;
			surprise = new Surprise(GameData.gameProfile);
			surpriseRect = surprise.surpriseRect;
			int ani[][] = { { 8 }, { 9 } };
			surprise.makeAnimation(ani);
			surpriseThread = new Thread(surprise);
			surpriseThread.start();
		}
		if (surpriseCatched) {
			surprise.surpriseCatched();
			surpriseCatched = false;
		}
		if (surpriseThread != null && surpriseThread.isAlive()) {
			surprise.drawself(canvas);
		} else {
			surpriseOccured = false;
			surpriseRect = null;
		}
	}

	public void drawBomb(Canvas canvas) {
		if (bomb != null && bomb.st.isAlive()) {
			bomb.drawself(canvas);
			ast_boom.MicNO = 14;
			ast_boom.soundon = true;
		}

	}

	public void killing() {
		Rect BoomRange = new Rect();
		if (bomb != null) {
			BoomRange.left = (int) bomb.getxPos() - 90;
			BoomRange.top = (int) bomb.getyPos() - 90;
			BoomRange.right = (int) bomb.getxPos() + 90;
			BoomRange.bottom = (int) bomb.getyPos() + 90;
		}
		for (int i = 0; i < GameData.MapRows; i++) {
			for (int j = 0; j < GameData.MapCols; j++) {
				if (Tower[i][j] != null
						&& Tower[i][j].towerstatus != GameData.NOT_BUILT) {
					if (BoomRange.contains((int) Tower[i][j].getxPos(),
							(int) Tower[i][j].getyPos()))
						Tower[i][j].kill();
				}
			}
		}
		for (int i = 0; i < monsterNumber; i++) {
			if (monsters[i].st.isAlive()) {
				if (BoomRange.contains((int) monsters[i].getxPos(),
						(int) monsters[i].getyPos()))
					monsters[i].kill();
			}
		}
	}

	public void nextWave(int currentStage) {
		monsterNumber = 5 + currentStage;
		monsters = new Monster[monsterNumber];

		sqt = new StartQueueThread();
		for (int i = 0; i < monsterNumber; i++) {
			int monsterType;
			int line;
			if (currentStage < 3)
				line = (GameData.rnd.nextInt(2) + 1) * 80 + 80;
			else
				line = GameData.rnd.nextInt(4) * 80 + 80;
			if (currentStage % 3 == 2 && i == monsterNumber - 1)
				monsterType = 6;
			else
				monsterType = GameData.rnd.nextInt(2) + 4;
			monsters[i] = new Monster(800, line, monsterType);
			monsters[i].setCurrentSegment(0);
			switch (monsterType) {	
			case 4:
				monsters[i].makeAnimation(GameData.monsterBlack);
				break;
			case 5:
				monsters[i].makeAnimation(GameData.monsterWhite);
				break;
			case 6:
				monsters[i].makeAnimation(GameData.Boss);
				break;

			}
			monsters[i].levelUp(currentStage);
			if (i == monsterNumber - 1)
				sqt.addSprite(10000, monsters[i]);
			else
				sqt.addSprite(GameData.rnd.nextInt(2000) + 500, monsters[i]);

		}
		if (!sqt.isAlive())
			sqt.start();

	}

	public boolean stageFinished() {
		for (int i = 0; i < monsterNumber; i++) {
			if (!monsters[i].isdead())
				return false;
		}
		return true;
	}

	public void drawUI(Canvas canvas) {
		Paint paint = new Paint();
		paint.setColor(Color.BLACK);
		paint.setAlpha(0x40);
		Paint paint_score = new Paint();
		paint_score.setColor(Color.RED);
		paint_score.setTextSize(20f);
		// game UI
		canvas.drawRect(0, 400, 800, 480, paint);
		BitmapManager.DrawGameUIResource(2, canvas, GameData.BuildMenu.left,
				GameData.BuildMenu.top, null);

		// score

		canvas.drawText("Score:" + GameData.gameProfile.score, 650, 450,
				paint_score);

		// BOMB TOOL NUM
		BitmapManager.DrawGameUIResource(0, canvas, 450, 400, null);
		Paint paint_Bomb = new Paint();
		paint_Bomb.setTextSize(24f);
		paint_Bomb.setColor(Color.WHITE);

		String bombnum1 = Integer.toString(GameData.gameProfile.BombNumber);
		canvas.drawText("x" + bombnum1, 520, 450, paint_Bomb);

		// Money
		BitmapManager.DrawGameUIResource(4, canvas, 300, 400, null);
		Paint paint_Money = new Paint();
		paint_Money.setTextSize(24f);
		paint_Money.setColor(Color.YELLOW);

		String Moneynum1 = Integer.toString(GameData.gameProfile.Money);
		canvas.drawText("x" + Moneynum1, 360, 450, paint_Money);
		if (touchRecord == 1) {

			canvas.drawRect(0, 0, 800, 80, paint);

			if (GameData.gameProfile.Money >= 80) {
				if (BuildSelect == GameData.FIRETOWER) {
					BitmapManager.DrawTower(5, canvas, GameData.Tower1.left,
							GameData.Tower1.top, null);
				} else {
					BitmapManager.DrawTower(1, canvas, GameData.Tower1.left,
							GameData.Tower1.top, null);
				}

			} else {
				BitmapManager.DrawTower(1, canvas, GameData.Tower1.left,
						GameData.Tower1.top, paint);
			}

			if (GameData.gameProfile.Money >= 150) {
				if (BuildSelect == GameData.DEFTOWER) {
					BitmapManager.DrawTower(8, canvas, GameData.Tower2.left,
							GameData.Tower2.top, null);
				} else {
					BitmapManager.DrawTower(3, canvas, GameData.Tower2.left,
							GameData.Tower2.top, null);
				}

			} else {
				BitmapManager.DrawTower(3, canvas, GameData.Tower2.left,
						GameData.Tower2.top, paint);
			}

			if (GameData.gameProfile.Money >= 300) {
				if (BuildSelect == GameData.NATURETOWER) {
					BitmapManager.DrawTower(15, canvas, GameData.Tower3.left,
							GameData.Tower3.top, null);
				} else {
					BitmapManager.DrawTower(11, canvas, GameData.Tower3.left,
							GameData.Tower3.top, null);
				}
			} else {

				BitmapManager.DrawTower(11, canvas, GameData.Tower3.left,

				GameData.Tower3.top, paint);

			}

			if (GameData.gameProfile.Money >= 800) {
				if (BuildSelect == GameData.THUNDERTOWER) {
					BitmapManager.DrawTower(25, canvas, GameData.Tower4.left,
							GameData.Tower4.top, null);
				} else {
					BitmapManager.DrawTower(21, canvas, GameData.Tower4.left,
							GameData.Tower4.top, null);
				}

			} else {
				BitmapManager.DrawTower(21, canvas, GameData.Tower4.left,
						GameData.Tower4.top, paint);
			}

			BitmapManager.DrawTower(4, canvas, GameData.EndBuild.left,
					GameData.EndBuild.top, null);
		}

		if (selected_TowerNo != 0) {
			for (selectedRect = 0; selectedRect < 32; selectedRect++) {
				selectedRow = (int) Math.floor(selectedRect / 8);
				selectedCol = selectedRect % 8;
				temp = tempRect.get(selectedRect);
				if (Tower[selectedRow][selectedCol] == null) {
					BitmapManager.DrawGameUIResource(3, canvas, temp.left,
							temp.top, paint);

				} else {
					if (Tower[selectedRow][selectedCol].isdead()) {
						BitmapManager.DrawGameUIResource(3, canvas, temp.left,
								temp.top, paint);
					}

				}
			}
		}

	}

	public void doDraw(Canvas canvas) {

		// Paint paint = new Paint();
		// paint.setAlpha(50);o
		// if((!spriteMonsters[0][0].isdead())&&(testOT.at==null))
		// testOT.attack(spriteMonsters[0][0],GameData.TOWERFIREATTACK);

		Paint paint = new Paint();
		paint.setColor(Color.BLACK);
		paint.setAlpha(0x40);

		// BitmapManager.DrawbackgroundResource(0, canvas, bgx, bgy, null);
		if (lost())
			status = 2;
		else {
			if (stageFinished() && !sqt.isAlive()) {
				Paint tmppaint = new Paint();
				tmppaint.setColor(Color.RED);
				tmppaint.setTextSize(100f);
				currentstage++;
				text = new Text("Stage " + (currentstage+1), 200f, 200f, tmppaint);
				text.start();
				GameData.gameProfile.score += (currentstage + 4) * 100;
				GameData.gameProfile.Money += 200 + currentstage * 50;
				nextWave(currentstage);
			}
		}

		switch (status) {
		case 0:
			BitmapManager.DrawbackgroundResource(0, canvas, bgx, bgy, null);
			break;

		case 1:
			BitmapManager.DrawbackgroundResource(0, canvas, 0, 0, null);
			if (text != null && text.isAlive()) {
				canvas.drawText(text.str, text.xPos, text.yPos, text.paint);
			}
			cleanThread();

			drawUI(canvas);
			drawBomb(canvas);
			drawSurprise(canvas);
			drawTowers(canvas);
			drawMonsters(canvas);

			if (onbackevent) {
				canvas.drawRect(0, 0, 800, 480, paint);
				BitmapManager.DrawGameUIResource(20, canvas, 250, 150, null);
			}

			drawAttack(canvas);
			break;
		case 2:
			ast_monsterwhitelack.soundon = false;
			ast_monsterwhite.soundon = false;
			ast_monsterboss.soundon = false;
			ast_thunder.soundon = false;
			ast_fire.soundon = false;
			ast_nature.soundon = false;
			gameover_mic.MicNO = 15;
			gameover_mic.soundon = true;
			Paint lost_paint = new Paint();
			lost_paint.setColor(Color.BLACK);
			lost_paint.setTextSize(100f);
			BitmapManager.DrawbackgroundResource(0, canvas, 0, 0, null);
			BitmapManager.DrawGameUIResource(30, canvas, 200, 40, null);
			lost_paint.setTextSize(24f);
			canvas.drawText(GameData.gameProfile.timeUsed(), 360, 200,
					lost_paint);
			canvas.drawText("" + GameData.gameProfile.score, 360, 255,
					lost_paint);
		}
	}

	public boolean gameTouch(int x, int y) {

		// press buildmenu
		if (GameData.Bomb.contains(x, y)) {
			if (GameData.gameProfile.BombNumber > 0) {
				bomb = new Bomb();
				bomb.makeAnimation(GameData.BOOM);
				bomb.startAnimation();
				killing();
				GameData.gameProfile.BombNumber--;
			}
		}
		if (GameData.BuildMenu.contains(x, y)) {
			pause();
			touchRecord = 1;
		}

		// record which tower has been choose
		if (touchRecord == 1) {
			if (GameData.Tower1.contains(x, y)) {
				if (GameData.gameProfile.Money >= 80)
					selected_TowerNo = 1;
				BuildSelect = GameData.FIRETOWER;
			}
			if (GameData.Tower2.contains(x, y)) {
				if (GameData.gameProfile.Money >= 150)
					selected_TowerNo = 2;
				BuildSelect = GameData.DEFTOWER;
			}
			if (GameData.Tower3.contains(x, y)) {
				if (GameData.gameProfile.Money >= 300)
					selected_TowerNo = 3;
				BuildSelect = GameData.NATURETOWER;
			}
			if (GameData.Tower4.contains(x, y)) {
				if (GameData.gameProfile.Money >= 800)
					selected_TowerNo = 4;
				BuildSelect = GameData.THUNDERTOWER;
			}

		}
		// finish build && realize the tower(set its animation)
		if (GameData.EndBuild.contains(x, y)) {
			resume();
			selected_TowerNo = 0;
			touchRecord = 0;
			BuildSelect = -1;

			for (selectedRect = 0; selectedRect < 32; selectedRect++) {
				selectedRow = (int) Math.floor(selectedRect / 8);
				selectedCol = selectedRect % 8;
				temp = tempRect.get(selectedRect);
				if (Tower[selectedRow][selectedCol] != null
						&& !Tower[selectedRow][selectedCol].isdead()) {
					if (Tower[selectedRow][selectedCol].towerstatus == GameData.IS_BUILDING) {
						Tower[selectedRow][selectedCol].towerstatus = GameData.HAVE_BUILT;
//						int moneyCost = 0;
//						switch (Tower[selectedRow][selectedCol].getAttribute()) {
//						case GameData.FIRETOWER:
//							moneyCost = 80;
//							break;
//						case GameData.DEFTOWER:
//							moneyCost = 150;
//							break;
//						case GameData.NATURETOWER:
//							moneyCost = 300;
//							break;
//						case GameData.THUNDERTOWER:
//							moneyCost = 8000;
//							break;
//						}
//
//						GameData.gameProfile.Money -= moneyCost;
					}

				}
			}
		}
		// surprise touched
		if (surpriseRect != null && surpriseRect.contains(x, y)) {
			surpriseCatched = true;
		}

		// building mode touch
		for (selectedRect = 0; selectedRect < 32; selectedRect++) {
			selectedRow = (int) Math.floor(selectedRect / 8);
			selectedCol = selectedRect % 8;
			temp = tempRect.get(selectedRect);
			if (temp.contains(x, y)) {
				// to cancel your building
				if (Tower[selectedRow][selectedCol] != null) {
					if (Tower[selectedRow][selectedCol].towerstatus == GameData.IS_BUILDING) {
							if(Tower[selectedRow][selectedCol].getAttribute()==GameData.FIRETOWER){
								GameData.gameProfile.Money+=80;
							}
							if(Tower[selectedRow][selectedCol].getAttribute()==GameData.DEFTOWER){
								GameData.gameProfile.Money+=150;
							}
							if(Tower[selectedRow][selectedCol].getAttribute()==GameData.NATURETOWER){
								GameData.gameProfile.Money+=300;
							}
							if(Tower[selectedRow][selectedCol].getAttribute()==GameData.THUNDERTOWER){
								GameData.gameProfile.Money+=800;
							}
							Tower[selectedRow][selectedCol].towerstatus = GameData.NOT_BUILT;
							Tower[selectedRow][selectedCol] = null;
							return true;
						}
					
					}
				
				// build and set the tower you choose
				switch (selected_TowerNo) {
				case 1:
					if ((Tower[selectedRow][selectedCol] == null
							|| ((Tower[selectedRow][selectedCol] != null && Tower[selectedRow][selectedCol]
									.isdead())))&&GameData.gameProfile.Money>=80) {
						Tower[selectedRow][selectedCol] = new OffTower(
								tempRect.get(selectedRow * 8 + selectedCol).left,
								tempRect.get(selectedRow * 8 + selectedCol).top,
								GameData.FIRETOWER);
						GameData.gameProfile.Money -= 80;
						Tower[selectedRow][selectedCol].towerstatus = GameData.IS_BUILDING;

						Tower[selectedRow][selectedCol]
								.makeAnimation(GameData.TowerFire);
						Tower[selectedRow][selectedCol].setCurrentSegment(0);
						
					}
					break;
				case 2:
					if ((Tower[selectedRow][selectedCol] == null
							|| ((Tower[selectedRow][selectedCol] != null && Tower[selectedRow][selectedCol]
									.isdead())))&&GameData.gameProfile.Money>=150){
						Tower[selectedRow][selectedCol] = new DefTower(tempRect
								.get(selectedRow * 8 + selectedCol).left,
								tempRect.get(selectedRow * 8 + selectedCol).top);
						Tower[selectedRow][selectedCol].towerstatus = GameData.IS_BUILDING;
						GameData.gameProfile.Money -= 150;
						Tower[selectedRow][selectedCol]
								.setAttribute(GameData.DEFTOWER);
						Tower[selectedRow][selectedCol]
								.makeAnimation(GameData.TowerDef);
						Tower[selectedRow][selectedCol].setCurrentSegment(0);
					}
					break;
				case 3:
					if ((Tower[selectedRow][selectedCol] == null
							|| ((Tower[selectedRow][selectedCol] != null && Tower[selectedRow][selectedCol]
									.isdead())))&&GameData.gameProfile.Money>=300) {
						Tower[selectedRow][selectedCol] = new OffTower(
								tempRect.get(selectedRow * 8 + selectedCol).left,
								tempRect.get(selectedRow * 8 + selectedCol).top,
								GameData.NATURETOWER);
						
						Tower[selectedRow][selectedCol].towerstatus = GameData.IS_BUILDING;
						GameData.gameProfile.Money -= 300;
						Tower[selectedRow][selectedCol]
								.makeAnimation(GameData.TowerNature);
						Tower[selectedRow][selectedCol].setCurrentSegment(0);
					}
					break;
				case 4:
					if ((Tower[selectedRow][selectedCol] == null
							|| ((Tower[selectedRow][selectedCol] != null && Tower[selectedRow][selectedCol]
									.isdead())))&&GameData.gameProfile.Money>=800) {
						Tower[selectedRow][selectedCol] = new OffTower(
								tempRect.get(selectedRow * 8 + selectedCol).left,
								tempRect.get(selectedRow * 8 + selectedCol).top,
								GameData.THUNDERTOWER);
						Tower[selectedRow][selectedCol].towerstatus = GameData.IS_BUILDING;
						GameData.gameProfile.Money -= 1000;
						Tower[selectedRow][selectedCol]
								.makeAnimation(GameData.TowerThunder);
						Tower[selectedRow][selectedCol].setCurrentSegment(0);
					}
					break;
				default:
					break;
				}

			}

		}

		if (status == 2) {

			if (GameData.Quit.contains(x, y)) {

				GameMicPool.release();

				vs.AfhHandler.sendEmptyMessage(2);

			}
		}
		if (paused && touchRecord != 1) {
			if (GameData.Title.contains(x, y)) {
				stop();

				// GameMicPool.release();
				vs.AfhHandler.sendEmptyMessage(2);

				paused = false;
				onbackevent = false;

			}

			if (GameData.Continue.contains(x, y)) {

				resume();

				paused = false;

				onbackevent = false;

			}
		}

		return true;
	}

	public boolean KeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			onbackevent = true;
			pause();
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {

		gt.DrawOn = true;
		if (!gt.isAlive()) {
			gt.start();
		}
		if (!ast_fire.isAlive()) {
			ast_fire.start();
		}
		if (!ast_nature.isAlive()) {
			ast_nature.start();
		}
		if (!ast_thunder.isAlive()) {
			ast_thunder.start();
		}
		if (!ast_monsterwhitelack.isAlive()) {
			ast_monsterwhitelack.start();
		}
		if (!ast_monsterwhite.isAlive()) {
			ast_monsterwhite.start();
		}
		if (!ast_monsterboss.isAlive()) {
			ast_monsterboss.start();
		}
		if (!gameover_mic.isAlive()) {
			gameover_mic.start();
		}
		if (!ast_boom.isAlive()) {
			ast_boom.start();
		}
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		gt.DrawOn = false;
		gt.flag = false;

	}

}